package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.DubboMethodConstant;
import cc.rengu.igas.bomp.common.dao.AlipayMchntInfoMapper;
import cc.rengu.igas.bomp.common.dao.MchntBaseInfoMapper;
import cc.rengu.igas.bomp.common.dao.MchntImageInfoMapper;
import cc.rengu.igas.bomp.common.dao.MchntSignInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.AlipayMchntInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntBaseInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntImageInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntSignInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.AlipayMchntInfo;
import cc.rengu.igas.bomp.common.entity.MchntBaseInfo;
import cc.rengu.igas.bomp.common.entity.MchntImageInfo;
import cc.rengu.igas.bomp.common.entity.MchntSignInfo;
import cc.rengu.igas.bomp.common.enums.ImageTypeEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.core.service.base.ManageService;
import cc.rengu.igas.bomp.facade.request.ApplyMchntAuthTokenRequest;
import cc.rengu.igas.bomp.facade.response.ApplyMchntAuthTokenResponse;
import cc.rengu.igas.channel.alipay.facade.base.Header;
import cc.rengu.igas.channel.alipay.facade.bean.AddressInfo;
import cc.rengu.igas.channel.alipay.facade.bean.AppAuthTokenInfo;
import cc.rengu.igas.channel.alipay.facade.bean.ContactInfo;
import cc.rengu.igas.channel.alipay.facade.bean.SignInfo;
import cc.rengu.igas.channel.alipay.facade.request.AliCreateMerchantRequest;
import cc.rengu.igas.channel.alipay.facade.request.AliGetAppAuthTokenRequest;
import cc.rengu.igas.channel.alipay.facade.response.AliCreateMerchantResponse;
import cc.rengu.igas.channel.alipay.facade.response.AliGetAppAuthTokenResponse;
import cc.rengu.igas.channel.alipay.facade.result.Result;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * Created by wangcheng on 2021/11/12 11:30
 */
public class ApplyMchntAuthTokenService extends ManageService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        ApplyMchntAuthTokenRequest applyMchntAuthTokenRequest = new ApplyMchntAuthTokenRequest();
        ConvertUtil.convertOutput(applyMchntAuthTokenRequest);
        return applyMchntAuthTokenRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ApplyMchntAuthTokenRequest applyMchntAuthTokenRequest = (ApplyMchntAuthTokenRequest) request;
        ApplyMchntAuthTokenResponse applyMchntAuthTokenResponse = new ApplyMchntAuthTokenResponse();
        applyMchntAuthTokenResponse.setHeader(applyMchntAuthTokenRequest.getHeader());
        String instId = applyMchntAuthTokenRequest.getHeader().getInstId();
        String mchntNo = applyMchntAuthTokenRequest.getMchntNo();
        String appAuthCode = applyMchntAuthTokenRequest.getAppAuthCode();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        if (StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(appAuthCode)) {
            rglog.error("直联支付宝回调获取商户应用授权请求参数有误,instId:<{}>,mchntNo:<{}>,appAuthCode:<{}>", instId, mchntNo, appAuthCode);
            throw new BizException(RespCodeEnum.PARAM_ERROR.getRespCode(), RespCodeEnum.PARAM_ERROR.getRespDesc());
        }

        /* 获取支付宝商户信息 */
        MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        AlipayMchntInfoMapper alipayMchntInfoMapper = new AlipayMchntInfoMapperImpl();
        AlipayMchntInfo alipayMchntInfo = alipayMchntInfoMapper.selectAlipayMchntInfoByPrimaryKey(instId, mchntNo);
        if (null == mchntBaseInfo || null == alipayMchntInfo) {
            rglog.error("支付宝商户信息不存在,instId:<{}>,mchntNo:<{}>", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        /* 调用支付宝获取商户应用授权TOKEN */
        DubboService dubboService = new DubboServiceImpl();
        AliGetAppAuthTokenRequest aliGetAppAuthTokenRequest = new AliGetAppAuthTokenRequest();
        Header header = new Header();
        BeanUtil.beanCopy(applyMchntAuthTokenRequest.getHeader(), header);
        header.setSrcSysId(AppParamConstant.SYS_ID);
        header.setTxnNum("agetappauthtoken");
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        aliGetAppAuthTokenRequest.setHeader(header);
        aliGetAppAuthTokenRequest.setAppAuthCode(appAuthCode);
        aliGetAppAuthTokenRequest.setChannelId(ChannelEnum.ALIP.getChannelType());
        aliGetAppAuthTokenRequest.setChannelType(alipayMchntInfo.getDstChannelType());
        Result<AliGetAppAuthTokenResponse> callResult = (Result<AliGetAppAuthTokenResponse>) dubboService.callDubboService(DubboMethodConstant.DUBBO_ALIPAY_MCHNT_SERVICE, "getAppAuthToken", aliGetAppAuthTokenRequest);
        if (null == callResult || !callResult.isSuccess() || null == callResult.getResult() || null == callResult.getResult().getAppAuthTokenInfoList() ||
                callResult.getResult().getAppAuthTokenInfoList().isEmpty() || !RespCodeEnum.TRANS_SUCCESS.getRespCode().equals(callResult.getResult().getRespCode())) {
            rglog.error("获取商户应用授权TOKEN失败！");
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        AppAuthTokenInfo appAuthTokenInfo = callResult.getResult().getAppAuthTokenInfoList().get(0);
        alipayMchntInfo.setAppAuthToken(appAuthTokenInfo.getAppAuthToken());
        alipayMchntInfo.setAuthAppId(appAuthTokenInfo.getAuthAppId());
        alipayMchntInfo.setAlipayMchntNo(appAuthTokenInfo.getUserId());

        /* 调用支付宝代商户签约 */
        header.setTxnNum("acreatemchnt");
        header.setTraceNo(sysSeqNum + RandomUtil.randomNumStr(4));
        AliCreateMerchantRequest aliCreateMerchantRequest = new AliCreateMerchantRequest();
        aliCreateMerchantRequest.setHeader(header);
        BeanUtil.beanCopy(alipayMchntInfo, aliCreateMerchantRequest);
        aliCreateMerchantRequest.setMchntName(mchntBaseInfo.getMchntName());
        /* 商户MCC */
        aliCreateMerchantRequest.setSource(alipayMchntInfo.getAlipayMchntNo());
        aliCreateMerchantRequest.setMchntType(mchntBaseInfo.getIndustryType());
        aliCreateMerchantRequest.setMchntAbbr(mchntBaseInfo.getMchntSimpleName());
        aliCreateMerchantRequest.setAlipayCategory(alipayMchntInfo.getAlipayCategory());
        //客服电话
        aliCreateMerchantRequest.setServicePhone(mchntBaseInfo.getMchntContactPhone());
        aliCreateMerchantRequest.setChannelId(ChannelEnum.ALIP.getChannelType());
        aliCreateMerchantRequest.setChannelType(alipayMchntInfo.getDstChannelType());
        /* 联系人信息 */
        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        MchntSignInfo mchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, mchntNo);
        ContactInfo contactInfo = new ContactInfo();
        contactInfo.setContact(mchntSignInfo.getArtifName());
        contactInfo.setContactTelephone(mchntSignInfo.getArtifMobile());
        contactInfo.setContactPhone(mchntSignInfo.getArtifMobile());
        contactInfo.setContactEmail(mchntSignInfo.getArtifEmail());
        contactInfo.setContactJobType("06");
        contactInfo.setContactType("LEGAL_PERSON");
        contactInfo.setCertId(mchntSignInfo.getArtifCertNo());
        aliCreateMerchantRequest.setContactInfoList(Collections.singletonList(contactInfo));
        //签约相关信息
        SignInfo signInfo = new SignInfo();
        signInfo.setBusinessLicenseNo(mchntSignInfo.getLicenceCode());
        //获取商户签约影像信息
        MchntImageInfoMapper mchntImageInfoMapper = new MchntImageInfoMapperImpl();
        List<MchntImageInfo> mchntImageInfoList = mchntImageInfoMapper.selectMchntImageInfoByMchntNo(instId, mchntNo);
        if (null != mchntImageInfoList && !mchntImageInfoList.isEmpty()) {
            SysParamMapper sysParamMapper = new SysParamMapperImpl();
            SysParam localUrlPrefix = sysParamMapper.selectSysParamByPrimaryKey(instId, BompAppParamConstant.IMAGE_STORAGE_PARAM_TYPE, BompAppParamConstant.LOCAL_IMAGE_STORAGE_PATH);
            if (null == localUrlPrefix) {
                rglog.error("查询系统参数表，根据机构获取图片存储服务器路径为空！InstId：<{}>!", instId);
                throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }
            //共享存储文件夹路径
            String shareStorageUrl = localUrlPrefix.getParamValue().trim().endsWith(File.separator) ? localUrlPrefix.getParamValue().trim() : localUrlPrefix.getParamValue().trim() + File.separator;
            //营销执照图片
            Optional<MchntImageInfo> mchntImageInfoOpt = mchntImageInfoList.stream().filter(item -> item.getImageType().equals(ImageTypeEnum.BUSINESS_LICENSE.getImageType())).findFirst();
            mchntImageInfoOpt.ifPresent(mchntImageInfo -> signInfo.setBusinessLicensePic(shareStorageUrl + mchntImageInfo.getImageLocalPath()));
            //店铺内景照
            mchntImageInfoOpt = mchntImageInfoList.stream().filter(item -> item.getImageType().equals(ImageTypeEnum.BUSINESS_SITE_PHOTO.getImageType())).findFirst();
            mchntImageInfoOpt.ifPresent(mchntImageInfo -> signInfo.setShopScenePic(shareStorageUrl + mchntImageInfo.getImageLocalPath()));
            //店铺门头照
            mchntImageInfoOpt = mchntImageInfoList.stream().filter(item -> item.getImageType().equals(ImageTypeEnum.SHOP_FRONT_PHOTO.getImageType())).findFirst();
            mchntImageInfoOpt.ifPresent(mchntImageInfo -> signInfo.setShopSignBoardPic(shareStorageUrl + mchntImageInfo.getImageLocalPath()));
        }
        aliCreateMerchantRequest.setSignInfo(signInfo);
        /* 地址信息 */
        AddressInfo addressInfo = new AddressInfo();
        addressInfo.setProvinceCode(mchntBaseInfo.getMchntBizProvince());
        addressInfo.setCityCode(mchntBaseInfo.getMchntBizCity());
        addressInfo.setDistrictCode(mchntBaseInfo.getMchntBizRegion());
        addressInfo.setAddress(mchntBaseInfo.getMchntBizAddr());
        aliCreateMerchantRequest.setAddressInfoList(Collections.singletonList(addressInfo));
        /* 直联支付宝商户代签约 */
        Result<AliCreateMerchantResponse> aliResult = (Result<AliCreateMerchantResponse>) dubboService.callDubboService(DubboMethodConstant.DUBBO_ALIPAY_MCHNT_SERVICE, "aliCreateMerchant", aliCreateMerchantRequest);
        if (null == aliResult || !aliResult.isSuccess() || !DubboMethodConstant.DUBBO_SUCCESS.equals(aliResult.getResult().getRespCode())) {
            rglog.error("支付宝直联商户入驻代签约失败!");
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        alipayMchntInfo.setBatchNo(aliResult.getResult().getBatchNo());
        alipayMchntInfo.setAlipayEntryFlag("00");
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        /* 更新支付宝商户信息 */
        int iReturnCode = alipayMchntInfoMapper.updateAlipayMchntInfoById(alipayMchntInfo);
        if (0 != iReturnCode) {
            rglog.error("更新支付商宝商户信息失败:{},iReturnCode:{}", JSON.toJSONString(alipayMchntInfo), iReturnCode);
            dbsUtil.dbsEndTransaction(false);
            throw new BizException(RespCodeEnum.CREATE_ALIPAY_MACHNT_INFO_ERROR.getRespCode(), RespCodeEnum.CREATE_ALIPAY_MACHNT_INFO_ERROR.getRespDesc());
        }
        dbsUtil.dbsEndTransaction(true);

        /* 组装应答报文 */
        BizResponse bizResponse = new BizResponse();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(applyMchntAuthTokenResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        ApplyMchntAuthTokenResponse applyMchntAuthTokenResponse = (ApplyMchntAuthTokenResponse) bizResponse.getResult();
        ConvertUtil.convertInput(applyMchntAuthTokenResponse);
    }
}
